﻿package {
	import flash.display.*;
	import flash.events.*;
	import flash.geom.*;
	
	public class Zombie extends Sprite {
		
		public var isAlive = true;
		public var isHurled = false;
		private var startPoint = null;
		private var velocity:Point = null;
		private var targetPoint:Point = null;
		private var hurlSteps:Number = 10;
		
		private var zombieSprite:ZombieSprite;
		private var defaultScale = 0.8;
		private var maximumScale = 3.0;
		private var timeToDie = 100;
		private var lifeCounter = 0;
		private var direction:Number = 0;
		private var attackDistance:Number = 40;
	
		public function Zombie()
		{
			init();
		}
		
		private function init()
		{
			zombieSprite = new ZombieSprite();
			zombieSprite.gotoAndStop(6);
			
			addChild(zombieSprite);
			this.scaleX = this.scaleY = defaultScale + ((Math.random() * 0.1) - 0.05);
			
			setDirection(Math.floor(Math.random() * 360));
		}
		
		public function step()
		{
			lifeCounter++;
			
			if (lifeCounter >= timeToDie)
			{
				//die()
			}

			if (isHurled) // move zombie towards its target a little bit
			{
				this.x += velocity.x;
				this.y += velocity.y;
				this.scaleX = this.scaleY = flightScale();
				this.rotation += 20;
				
				if ( this.y <= targetPoint.y )
				{
					this.rotation = 0;
					isHurled = false;
				}
			}
			else if (isAlive)
			{
				moveMe()
			}
		}
		
		public function moveMe()
		{
			var dX = Math.cos(getDirection() * (Math.PI / 180));
			var dY = Math.sin(getDirection() * (Math.PI / 180));
			
			var step = 2;

			this.x += dX * step;
			this.y += dY * step;
						
			var room = (parent as Room);
			var doTurnAround = false;
			if (this.x >= room.rectangle.width)
			{
				this.x = room.rectangle.width;
				doTurnAround = true;
			}
			else if (this.x < 0)
			{
				this.x = 0;
				doTurnAround = true;
			}

			if (this.y >= room.rectangle.height)
			{
				this.y = room.rectangle.height;
				doTurnAround = true;
			}
			else if (this.y < 0)
			{
				this.y = 0;
				doTurnAround = true;
			}
			
			if (doTurnAround)
			{
				setDirection(getDirection() + 90 + (Math.random() * 360) - 180);
			}
		}
		
		public function canAttack(human:Human)
		{
			var yDiff = Math.abs(human.y - this.y);
			var xDiff = Math.abs(human.x - this.x);
			return(!isHurled && yDiff <= attackDistance && xDiff <= attackDistance);			
		}
		
		public function die()
		{
			isAlive = false;
			zombieSprite.gotoAndStop(2);
			zombieSprite.rotation = 90;
		}

		public function getDirection():Number
		{
			return this.direction;
		}

		public function setDirection(value:Number):void
		{
			this.direction = value;
			var frameNumber = this.getFrameNumber();
			if (zombieSprite)
			{
				zombieSprite.gotoAndStop(frameNumber);			
			}
		}

		public function getFrameNumber():uint
		{
			var normalDirection:Number = this.direction % 360;
			normalDirection += 360;
			var frameNumber:uint = Math.abs(((normalDirection % 360) / 45)) + 1;
			switch( frameNumber ) {
				case 1:
					return 6;
					break;
				case 2:
					return 5;
					break;
				case 3:
					return 4;
					break;
				case 4:
					return 3;
					break;
				case 5:
					return 2;
					break;
				case 6:
					return 1;
					break;
				case 7:
					return 8;
					break;
				case 8:
					return 7;
					break;				
			}
			return frameNumber;
		}
		
		public function hurlTo(targetCoords:Object)
		{
			velocity = new Point();
			startPoint = new Point();
			targetPoint = new Point();
			targetPoint.x = targetCoords["x"]+ ((Math.random() * 60) - 30);
			targetPoint.y = targetCoords["y"]+ ((Math.random() * 60) - 30);
			startPoint.x = this.x ;
			startPoint.y = this.y ;
			
			velocity.x = (targetPoint.x - this.x) / hurlSteps;
			velocity.y = (targetPoint.y - this.y) / hurlSteps;
			isHurled = true;
		}
	
		private function flightScale()
		{
			var scaleDifference = maximumScale - defaultScale;
			
			var scalePercentage = ((startPoint.y - this.y) * 2) / (startPoint.y - targetPoint.y);
			
			var newScale = Math.sin(scalePercentage * Math.PI/2) * scaleDifference;
			var scale = defaultScale + newScale;

			return scale;
		}
}
	
}